package com.lezhi.socialgram.api.moments;

import com.lezhi.socialgram.enums.ResultEnum;
import com.lezhi.socialgram.exception.SocialGramException;
import com.lezhi.socialgram.mapper.friend.FriendMapper;
import com.lezhi.socialgram.mapper.moments.CommentMapper;
import com.lezhi.socialgram.mapper.moments.MomentMapper;
import com.lezhi.socialgram.mapper.sys.CclMapper;
import com.lezhi.socialgram.mapper.sys.UserMapper;
import com.lezhi.socialgram.mapper.sys.UserPrivacyMapper;
import com.lezhi.socialgram.model.friend.MyLike;
import com.lezhi.socialgram.model.moments.Comment;
import com.lezhi.socialgram.model.moments.Moment;
import com.lezhi.socialgram.model.moments.MomentInfo;
import com.lezhi.socialgram.model.sys.Ccl;
import com.lezhi.socialgram.model.sys.TelNumSignInUser;
import com.lezhi.socialgram.model.sys.User;
import com.lezhi.socialgram.model.sys.UserPrivacy;
import com.lezhi.socialgram.service.moments.MomentService;
import com.lezhi.socialgram.util.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * Created by daizhen on 2017/4/6.
 */
@RestController
public class MomentApi {

    private static final Logger logger = LoggerFactory.getLogger(MomentApi.class);

    @Autowired
    MomentService momentService;

    @Autowired
    CclMapper cclMapper;

    @Autowired
    StringRedisTemplate stringRedisTemplate;

    @Autowired
    CommentMapper commentMapper;

    @Autowired
    UserMapper userMapper;

    @Autowired
    MomentMapper momentMapper;

    @Autowired
    UserPrivacyMapper userPrivacyMapper;

    @Autowired
    FriendMapper friendMapper;

    /**
     * 发布动态
     *
     * @param moment
     * @param bindingResult
     * @return
     */
    @PostMapping("/moment")
    public Result publishMoment(@RequestBody @Valid Moment moment, BindingResult bindingResult) {
        ValidUtils.valid(logger, bindingResult);
        return momentService.publishMoment(moment);
    }

    /**
     * 查询某人自己的时间线
     *
     * @param userId    用户id
     * @param momentId  最后一个动态id
     * @param operation 向上|向下滚动
     * @return
     */
    @GetMapping("moment/{userId}/{momentId}/{operation}")
    public Result queryMoment(@PathVariable("userId") Long userId, @PathVariable("momentId") Long momentId,
                              @PathVariable("operation") Integer operation) {
        return momentService.queryMomentsByUserId(userId, momentId, operation);
    }

    /**
     * 查询带好友部分的时间线
     *
     * @param userId    用户id
     * @param momentId  最后一个动态id
     * @param operation 向上|向下滚动
     * @return
     */
    @GetMapping("moment/friend/{userId}/{momentId}/{operation}")
    public Result queryFriendMomentsByUserId(@PathVariable("userId") Long userId, @PathVariable("momentId") Long momentId,
                                             @PathVariable("operation") Integer operation) {
        return momentService.queryFriendMomentsByUserId(userId, momentId, operation);
    }

    /**
     * 收藏帖子
     *
     * @param userId       用户id
     * @param monentId     动态id
     * @param momentUserId 动态发布者的id
     * @param operation    向上|向下滚动
     * @return code 0 data为null
     */
    @GetMapping("moment/collect/{userId}/{momentId}/{momentUserId}/{operation}")
    public Result collect(@PathVariable("userId") Long userId, @PathVariable("momentId") String monentId,
                          @PathVariable("momentUserId") Long momentUserId,
                          @PathVariable("operation") Long operation) {
        try {
            Ccl ccl = new Ccl();
            ccl.setUserId(userId);
            ccl.setMomentId(monentId);
            ccl.setMomentUserId(momentUserId);
            Ccl cl = cclMapper.queryCcl(ccl);
            if (cl == null) {//没有就新增
                ccl.setType(1);
                cclMapper.insertCcl(ccl);
            } else {
                if (operation == 1) {//修改
                    cl.setType(cl.getType() + 1);
                    cclMapper.updateCcl(cl);
                } else {//删除
                    if (cl.getType() > 1) {//有其他operation
                        cl.setType(cl.getType() - 1);
                        cclMapper.updateCcl(cl);
                    } else {//直接删除
                        cclMapper.deleteCcl(cl);
                    }
                }
            }
            stringRedisTemplate.opsForHash().increment(momentUserId + "user_count", Param.NEW_COLLECT_COUNT, 1);
            stringRedisTemplate.opsForHash().increment(momentUserId + "user_count", Param.SEEN_MY_MOMENT_TOTAL_COUNT, 1);
            return ResultUtils.success();
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw new SocialGramException(ResultEnum.INTERNAL_ERROR);
        }
    }

    /**
     * 赞帖子
     *
     * @param userId       用户id
     * @param momentId     动态id
     * @param momentUserId 动态发布者的id
     * @param operation    向上|向下滚动
     * @return code 0 data为null
     */
    @GetMapping("moment/like/{userId}/{momentId}/{momentUserId}/{operation}")
    public Result like(@PathVariable("userId") Long userId, @PathVariable("momentId") String momentId,
                       @PathVariable("momentUserId") Long momentUserId,
                       @PathVariable("operation") Long operation) {
        try {
            Ccl ccl = new Ccl();
            ccl.setUserId(userId);
            ccl.setMomentId(momentId);
            ccl.setMomentUserId(momentUserId);
            Ccl cl = cclMapper.queryCcl(ccl);
            if (cl == null) {//没有就新增
                ccl.setType(3);
                cclMapper.insertCcl(ccl);
                Moment moment = new Moment();
                moment.setMomentId(momentId);
                moment.setTable(TableUtils.getTableNameWithDate(Moment.class, null).getTableName());
                moment = momentMapper.queryMomentById(moment);
                moment.setTable(TableUtils.getTableNameWithDate(Moment.class, null).getTableName());
                String likedFansIds = moment.getLikedFansIds();
                if (likedFansIds == null) {
                    moment.setLikedFansIds("#" + userId + "#");
                } else {
                    moment.setLikedFansIds(moment.getLikedFansIds() + ",#" + userId + "#");
                }
                momentMapper.updateMoment(moment);
                stringRedisTemplate.opsForHash().increment(momentId + "_count", "likedCount", 1);
                stringRedisTemplate.opsForHash().increment(momentUserId + "user_count", Param.NEW_LIKE_MY_MOMENT_COUNT, 1);
                stringRedisTemplate.opsForHash().increment(momentUserId + "user_count", Param.LIKE_MY_MOMENT_TOTAL_COUNT, 1);
            } else {
                if (operation == 1) {//修改
                    cl.setType(cl.getType() + 3);
                    cclMapper.updateCcl(cl);
                    Moment moment = new Moment();
                    moment.setMomentId(momentId);
                    moment.setTable(TableUtils.getTableNameWithDate(Moment.class, null).getTableName());
                    moment = momentMapper.queryMomentById(moment);
                    moment.setTable(TableUtils.getTableNameWithDate(Moment.class, null).getTableName());
                    String likedFansIds = moment.getLikedFansIds();
                    if (likedFansIds == null) {
                        moment.setLikedFansIds("#" + userId + "#");
                    } else {
                        moment.setLikedFansIds(moment.getLikedFansIds() + ",#" + userId + "#");
                    }
                    momentMapper.updateMoment(moment);
                    stringRedisTemplate.opsForHash().increment(momentId + "_count", "likedCount", 1);
                    stringRedisTemplate.opsForHash().increment(momentUserId + "user_count", Param.NEW_LIKE_MY_MOMENT_COUNT, 1);
                    stringRedisTemplate.opsForHash().increment(momentUserId + "user_count", Param.LIKE_MY_MOMENT_TOTAL_COUNT, 1);
                } else {//删除
                    if (cl.getType() > 3) {//有其他operation
                        cl.setType(cl.getType() - 3);
                        cclMapper.updateCcl(cl);
                    } else {//直接删除
                        cclMapper.deleteCcl(cl);
                    }
                }
            }

            stringRedisTemplate.opsForHash().increment(momentId + "_count", "seenCount", 1);
            stringRedisTemplate.opsForHash().increment(momentUserId + "user_count", Param.SEEN_MY_MOMENT_TOTAL_COUNT, 1);
            return ResultUtils.success();
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw new SocialGramException(ResultEnum.INTERNAL_ERROR);
        }
    }

    /**
     * 发表评论
     *
     * @param comment       Long momentUserId; 动态发布者的id
     *                      String content; 评论内容
     *                      Long destCommentId; 针对某条评论进行回复
     *                      Long userId; 用户id
     *                      String momentId; 动态id
     * @param bindingResult //ignore
     * @return code 0 data为null
     */
    @PostMapping("/comment")
    public Result comment(@RequestBody @Valid Comment comment, BindingResult bindingResult) {
        ValidUtils.valid(logger, bindingResult);
        try {
            String momentId = comment.getMomentId();
            Long momentUserId = comment.getMomentUserId();
            stringRedisTemplate.opsForHash().increment(momentId + "_count", "commentsCount", 1);
            stringRedisTemplate.opsForHash().increment(momentId + "_count", "seenCount", 1);
            stringRedisTemplate.opsForHash().increment(momentUserId + "user_count", Param.SEEN_MY_MOMENT_TOTAL_COUNT, 1);
            String se = momentId.substring(momentId.indexOf("_") + 1, momentId.length());
            comment.setTable(TableUtils.getTableNameWithId(Comment.class, Long.parseLong(se), 100));
            comment.setCommentId(stringRedisTemplate.opsForValue().increment(Param.COMMENT_SEQUENCE, 1));
            commentMapper.insertComment(comment);
            return ResultUtils.success();
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw new SocialGramException(ResultEnum.INTERNAL_ERROR);
        }
    }

    /**
     * 查询评论
     *
     * @param momentId      动态id
     * @param lastCommentId 最后一个评论id
     * @param operation     向上|向下滚动
     * @return Long commentId; 评论id
     * Long momentUserId; 动态发布者id
     * Long content; 评论内容
     * Long destCommentId; 针对某条评论回复
     * Long userId; 发评论的人的id
     * String momentId; 动态id
     * Long createTime; 发表时间
     */
    @GetMapping("/comment/{momentId}/{lastCommentId}/{operation}")
    public Result comment(@PathVariable("momentId") String momentId,
                          @PathVariable("lastCommentId") Long lastCommentId,
                          @PathVariable("operation") Integer operation) {
        try {
            Comment comment = new Comment();
            String se = momentId.substring(momentId.indexOf("_") + 1, momentId.length());
            comment.setTable(TableUtils.getTableNameWithId(Comment.class, Long.parseLong(se), 100));
            comment.setCommentId(lastCommentId);
            comment.setOperation(operation);
            comment.setMomentId(momentId);
            List<Comment> comments = commentMapper.queryComment(comment);
            List<Comment> commentList = new CopyOnWriteArrayList<>();
            for (int i = 0; i < comments.size(); i++) {
                Comment co = comments.get(i);
                Long userId = co.getUserId();
                HashMap<String, Object> hashMap = new HashMap<>();
                hashMap.put("table", TableUtils.getTableNameWithId(TelNumSignInUser.class, userId, 10));
                hashMap.put("userId", userId);
                User user = userMapper.queryUser(hashMap);
                co.setNickname(user.getNicknameZh());
                co.setImageUrl(user.getUserImageUrl());
                commentList.add(co);
            }
            return ResultUtils.success(commentList);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw new SocialGramException(ResultEnum.INTERNAL_ERROR);
        }
    }

    /**
     * 查询动态详情
     *
     * @param momentId     动态id
     * @param momentUserId 动态发布者的id
     * @param userId       用户id
     * @return
     */
    @GetMapping("momentInfo/{momentId}/{momentUserId}/{userId}")
    public Result momentInfo(@PathVariable("momentId") String momentId,
                             @PathVariable("momentUserId") Long momentUserId,
                             @PathVariable("userId") Long userId) {
        try {
            MomentInfo momentInfo = new MomentInfo();
            //头像、昵称
            HashMap<String, Object> hashMap = new HashMap<>();
            hashMap.put("table", TableUtils.getTableNameWithId(TelNumSignInUser.class, momentUserId, 10));
            hashMap.put("userId", momentUserId);
            User user = userMapper.queryUser(hashMap);
            momentInfo.setMomentUserId(momentUserId);
            momentInfo.setMomentUserImageUrl(user != null ? user.getUserImageUrl() : null);
            momentInfo.setMomentUserNickname(user != null ? user.getNicknameZh() : null);
            //发表时间、文本内容、帖子是否大赏观看以及价格
            Moment moment = new Moment();
            moment.setMomentId(momentId);
            moment.setTable(TableUtils.getTableNameWithDate(Moment.class, null).getTableName());
            moment = momentMapper.queryMomentById(moment);
            momentInfo.setPublishTime(moment.getCreateTime());
            momentInfo.setContent(moment.getTextContent());
            momentInfo.setPrice(moment.getPrice());
            momentInfo.setMediaList(moment.getMedia_list());
            //点赞数、评论数、观看数、礼物数量
            Long seenCount = Long.parseLong(stringRedisTemplate.opsForHash().get(momentId + "_count", "seenCount") + "");
            Long likedCount = Long.parseLong(stringRedisTemplate.opsForHash().get(momentId + "_count", "likedCount") + "");
            Long commentsCount = Long.parseLong(stringRedisTemplate.opsForHash().get(momentId + "_count", "commentsCount") + "");
            Long giftsCount = Long.parseLong(stringRedisTemplate.opsForHash().get(momentId + "_count", "giftsCount") + "");
            momentInfo.setSeenCount(seenCount);
            momentInfo.setLikedCount(likedCount);
            momentInfo.setCommentsCount(commentsCount);
            momentInfo.setGiftsCount(giftsCount);
            //是否已点赞、是否已喜欢这个人
            String likedFansIds = moment.getLikedFansIds();
            if (likedFansIds != null && likedFansIds.indexOf("#" + userId + "#") >= 0) {
                momentInfo.setLikedThisMoment(1);
            } else {
                momentInfo.setLikedThisMoment(0);
            }
            MyLike myLike = new MyLike();
            myLike.setTable(TableUtils.getTableNameWithId(MyLike.class, userId, 100));
            myLike.setUid(userId);
            myLike.setFid(momentUserId);
            MyLike like = friendMapper.queryMyLikeById(myLike);
            if (like != null) {
                momentInfo.setLikedThisUser(1);
            } else {
                momentInfo.setLikedThisUser(0);
            }
            //是否允许陌生人评论、是否允许陌生人私信、是否允许陌生人下载
            UserPrivacy userPrivacy = new UserPrivacy();
            userPrivacy.setTable(TableUtils.getTableNameWithId(UserPrivacy.class, momentUserId, 10));
            userPrivacy.setUserId(momentUserId);
            UserPrivacy privacy = userPrivacyMapper.queryById(userPrivacy);
            momentInfo.setForbidMomentDownload(privacy != null ? privacy.getForbidDownloadMoment() : 0);
            momentInfo.setForbidStrangeComment(privacy != null ? privacy.getForbidStrangeComment() : 0);
            momentInfo.setForbidStrangeSendMsg(privacy != null ? privacy.getForbidStrangeLetter() : 0);
            momentInfo.setMomentId(momentId);
            momentInfo.setUserId(momentUserId);
            //是否已经付过费
            return ResultUtils.success(momentInfo);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            throw new SocialGramException(ResultEnum.INTERNAL_ERROR);
        }
    }


}
